package com.seeyon.v3x.mail.manager;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import com.alibaba.fastjson.JSONArray;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.seeyon.apps.kk.constants.Constants;
import com.seeyon.apps.kk.manager.FormDataBaseManager;
import com.seeyon.ctp.common.AbstractSystemInitializer;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.cache.CacheAccessable;
import com.seeyon.ctp.common.cache.CacheFactory;
import com.seeyon.ctp.common.cache.CacheObject;
import com.seeyon.ctp.common.config.manager.ConfigManager;
import com.seeyon.ctp.common.po.config.ConfigItem;
import com.seeyon.ctp.util.Strings;
import com.seeyon.ctp.util.TextEncoder;
import com.seeyon.ctp.util.XMLCoder;
import com.seeyon.v3x.mail.util.AffixList;
import com.seeyon.v3x.mail.util.ConnMailhost;
import com.seeyon.v3x.mail.util.MailInfo;
import com.seeyon.v3x.mail.util.MailTools;

public class MessageMailManagerImpl extends AbstractSystemInitializer implements MessageMailManager {

    private static Log log = LogFactory.getLog(MessageMailManagerImpl.class);

    // 系统邮箱设置 配置项
    private static final String SystemMailbox_ConfigCatrgory = "System_Mailbox_Setting";
    private static final String SystemMailbox_ConfigItem = "SystemMailAddress";
    private static final String Default_Suffer = "[A8]";
    private CacheObject<Boolean> hasSystemMailbox = null;

    private InternetAddress systemMailAddress = null;
    private CacheObject<String> MailAddress = null;
    private CacheObject<String> SMTPHost = null;
    private CacheObject<String> password = null;
    private CacheObject<String> suffer = null;
    private CacheObject<String> userName = null;
    private CacheObject<Integer> pop3Port = null;
    private CacheObject<Integer> smtpPort = null;

    // 邮件正文是否允许带链接以直接打开详细信息进行处理
    private CacheObject<Boolean> contentWithLink = null;
    //协同在线时发送邮件通知
    private CacheObject<Boolean> isSendOnline = null;
    // 邮件连接的有效期限 单位小时 默认24
    private CacheObject<Integer> contentLinkValidity = null;

    private Session session = null;
    private ConfigManager configManager;
    private final ExecutorService exec = Executors.newCachedThreadPool(new ThreadFactory() {
        private AtomicInteger threadNum = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "Mail_Thread_" + threadNum.getAndIncrement());
        }
    });
    //邮件发送超时次数
    private final int timeOutAmount = 3;
    private int timeOutIndex = 0;
    //等待邮件发送超时时间，单位为秒
    private final int timeOut = 30 * 60;

    public void setConfigManager(ConfigManager configManager) {
        this.configManager = configManager;
    }

    /**
     * 初始化方法
     */
    @Override
    public void initialize() {
        long start = System.currentTimeMillis();

        CacheAccessable factory = CacheFactory.getInstance(MessageMailManagerImpl.class);

        hasSystemMailbox = factory.createObject("systemMailHasSystemMailbox");

        MailAddress = factory.createObject("systemMailAddress");

        SMTPHost = factory.createObject("systemSMTPHost");

        password = factory.createObject("systemMailPassword");

        suffer = factory.createObject("systemMailSuffer");

        userName = factory.createObject("systemMailUserName");

        contentWithLink = factory.createObject("systemMailContentWithLink");

        pop3Port = factory.createObject("systemMailPop3Port");

        smtpPort = factory.createObject("systemMailSmtpPort");

        isSendOnline = factory.createObject("systemMailIsSendOnline");

        contentLinkValidity = factory.createObject("systemMailContentLinkValidity");

        hasSystemMailbox.set(false);

        contentWithLink.set(true);

        pop3Port.set(110);

        smtpPort.set(25);

        isSendOnline.set(true);

        contentLinkValidity.set(24);

        ConfigItem systemMailboxConfigItem = configManager.getConfigItem(SystemMailbox_ConfigCatrgory, SystemMailbox_ConfigItem);

        if (systemMailboxConfigItem != null) {
            String extConfigValue = systemMailboxConfigItem.getExtConfigValue();
            if (extConfigValue.startsWith("<")) {
                SystemEmailConfig sysMailConfig = (SystemEmailConfig) XMLCoder.decoder(extConfigValue);
                MailAddress.set(sysMailConfig.getEmailAddress());
                SMTPHost.set(sysMailConfig.getSmtpHost());
                password.set(sysMailConfig.getEmailPwd());
                contentWithLink.set(sysMailConfig.isAppendLink());
                contentLinkValidity.set(sysMailConfig.getAvailableTime());
                suffer.set(sysMailConfig.getSuffer());
                userName.set(sysMailConfig.getUserName());
                pop3Port.set(sysMailConfig.getPop3Port());
                smtpPort.set(sysMailConfig.getSmtpPort());
                isSendOnline.set(sysMailConfig.isSendOnline());
            } else {
                // 处理老用户的设置
                MailAddress.set(systemMailboxConfigItem.getConfigValue());
                String[] extItems = extConfigValue.split(",");
                SMTPHost.set(extItems[0]);
                password.set(TextEncoder.encode(extItems[2]));
                int toIntPop = pop3Port.get();
                toIntPop = toIntPop == 0 ? 110 : toIntPop;
                pop3Port.set(toIntPop);

                int toIntSmtp = smtpPort.get();
                toIntSmtp = toIntSmtp == 0 ? 25 : toIntSmtp;
                smtpPort.set(toIntSmtp);
                SystemEmailConfig emailConfig = new SystemEmailConfig(MailAddress.get(), SMTPHost.get(), password.get(), contentWithLink.get(), contentLinkValidity.get(), Default_Suffer, MailAddress.get(), pop3Port.get(), smtpPort.get(), isSendOnline.get());
                String newExtConfigValue = XMLCoder.encoder(emailConfig);
                systemMailboxConfigItem.setExtConfigValue(newExtConfigValue);
                configManager.updateConfigItem(systemMailboxConfigItem);
                suffer.set(emailConfig.getSuffer());
                userName.set(emailConfig.getUserName());
                isSendOnline.set(true);
            }

            // 对老数据的处理 suffer == null 表明不存在这个项 ，则更新数据库
            if (suffer.get() == null) {
                SystemEmailConfig emailConfig = new SystemEmailConfig(MailAddress.get(), SMTPHost.get(), password.get(), contentWithLink.get(), contentLinkValidity.get(), Default_Suffer, userName.get(), pop3Port.get(), smtpPort.get(), isSendOnline.get());
                String newExtConfigValue = XMLCoder.encoder(emailConfig);
                systemMailboxConfigItem.setExtConfigValue(newExtConfigValue);
                configManager.updateConfigItem(systemMailboxConfigItem);
                suffer.set(emailConfig.getSuffer());
                userName.set(emailConfig.getUserName());
            }

            if (userName.get() == null) {
                SystemEmailConfig emailConfig = new SystemEmailConfig(MailAddress.get(), SMTPHost.get(), password.get(), contentWithLink.get(), contentLinkValidity.get(), Default_Suffer, MailAddress.get(), pop3Port.get(), smtpPort.get(), isSendOnline.get());
                String newExtConfigValue = XMLCoder.encoder(emailConfig);
                systemMailboxConfigItem.setExtConfigValue(newExtConfigValue);
                configManager.updateConfigItem(systemMailboxConfigItem);
                userName.set(emailConfig.getUserName());
            }

//			session = Session.getInstance(this.getProps(SMTPHost), (Authenticator) new PasswordAuthenticator(userName, password));
            resetSysMailSession();
            try {
                systemMailAddress = new InternetAddress(MailAddress.get());
                hasSystemMailbox.set(true);
            } catch (Exception e) {
                log.error(e.getMessage() + " 系统邮箱Email地址不合法，不能使用邮件发送系统消息!");
                hasSystemMailbox.set(false);
            }
        } else {
            hasSystemMailbox.set(false);
            contentWithLink.set(false);
        }

        log.info("加载系统邮箱设置信息. 耗时: " + (System.currentTimeMillis() - start) + " MS");
    }

    /**
     * 判断管理员是否设置了系统邮箱
     */
    public boolean hasSystemMailbox() {
        return hasSystemMailbox.get();
    }

    /**
     * 通过邮件发送系统消息
     */
    public boolean sendMessageByMail(String to, String subject, String content, Date sendDate) {
        List<String> toMailList = new ArrayList<String>(1);
        toMailList.add(to);

        return this.sendMessageByMail(toMailList, subject, content, sendDate);
    }

    @Override
    public boolean sendMessageByMail(List<String> toMailList, List<String> ccMailList, String subject, String content, Date sendDate, AffixList affixList) {
        //kk  记录邮件发送日志  wtt 20200426
        Map<String, Object> logMap = new HashMap<String, Object>();
        logMap.put("接口名称", "系统邮件发送日志");
        logMap.put("调用模块", "邮件发送");//致远插件、启信宝接口
        logMap.put("调用人", "");
        logMap.put("收件人", toMailList);
        logMap.put("抄送人", ccMailList);
        logMap.put("经销商名称", subject);
        logMap.put("调用时间", sendDate);
        String errorMsg = "";
        if (hasSystemMailbox()) {
            int toMailErrorCount = 0; // 获取收件人错误邮箱出现的次数
            boolean toMailFlag = false;
            InternetAddress[] toMailArray = new InternetAddress[toMailList.size()];
            for (int i = 0; i < toMailList.size(); i++) {
                String kkemail = toMailList.get(i);
                // 防止出现经销商多个邮箱
                if (-1 != kkemail.indexOf(";")) {
                    toMailFlag = true;
                    String[] tempMail = kkemail.split(";");
                    toMailArray = Arrays.copyOf(toMailArray, toMailArray.length + (tempMail.length - 1));
                    for (int m = 0; m < tempMail.length; m++) {
                        try {
                            toMailArray[i + m] = new InternetAddress(tempMail[m]);
                        } catch (AddressException e) {
                            log.error("#强生客开,邮件地址不合法:" + tempMail[m], e);
                            continue;
                        }
                    }
                    continue;
                }
                try {
                    toMailArray[i - toMailErrorCount] = new InternetAddress(toMailList.get(i));
                } catch (AddressException e) {
                    toMailErrorCount++;
                    logMap.put("调用状态", "失败");
                    errorMsg += "邮件地址不合法:" + kkemail + ";";
                    log.error("邮件地址不合法:" + toMailList.get(i), e);
                    continue;
                }
            }
            // kk:处理产品收件人bug，有一个邮箱地址不合法，其他人员也收不到邮件  start
            int tSize = 0;
            if (toMailFlag) {
                tSize = toMailArray.length;
            } else {
                tSize = toMailList.size() - toMailErrorCount;
            }

            InternetAddress[] tMailArray = new InternetAddress[tSize];
            for (int i = 0; i < tMailArray.length; i++) {
                try {
                    tMailArray[i] = new InternetAddress(toMailArray[i].toString());
                } catch (AddressException e) {
                    log.error("#强生客开,邮件地址不合法:" + toMailArray[i], e);
                    continue;
                }
            }

            // kk: 处理产品收件人bug，有一个邮箱地址不合法，其他人员也收不到邮件 end

            int ccMailErrorCount = 0; // 获取抄送人错误邮箱出现的次数
            InternetAddress[] ccMailArray = new InternetAddress[ccMailList.size()];
            for (int i = 0; i < ccMailList.size(); i++) {
                String cckkemail = ccMailList.get(i);
                try {
                    ccMailArray[i] = new InternetAddress(ccMailList.get(i));
                } catch (AddressException e) {
                    ccMailErrorCount++;
                    logMap.put("调用状态", "失败");
                    errorMsg += "强生客开，抄送人邮件地址不合法:" + cckkemail + ";";
                    log.error("#强生客开，抄送人邮件地址不合法:" + ccMailList.get(i), e);
                    continue;
                }
            }

            // kk:处理产品抄送人bug，有一个邮箱地址不合法，其他人员也收不到邮件  start
            int ccSize = ccMailList.size() - ccMailErrorCount;
            InternetAddress[] cMailArray = new InternetAddress[ccSize];
            for (int i = 0; i < ccMailArray.length; i++) {
                try {
                    cMailArray[i] = new InternetAddress(ccMailArray[i].toString());
                } catch (AddressException e) {
                    log.error("#强生客开,邮件地址不合法:" + ccMailArray[i], e);
                    continue;
                }
            }

            log.info("toMailArray:" + JSONArray.toJSONString(toMailArray));
            log.info("tMailArray:" + JSONArray.toJSONString(tMailArray));
            log.info("ccMailArray:" + JSONArray.toJSONString(ccMailArray));
            log.info("cMailArray:" + JSONArray.toJSONString(cMailArray));
            // kk: 处理产品抄送人bug，有一个邮箱地址不合法，其他人员也收不到邮件 end

            if (toMailArray.length == 0) {
                return false;
            }

            if (session == null) {
                resetSysMailSession();
            }
            Message msg = null;
            try {
                boolean result = execMailTask(exec, timeOut, subject, content, tMailArray, cMailArray, affixList);
                if (result) {
                    logMap.put("调用状态", "发送成功");
                } else {
                    logMap.put("调用状态", "邮件服务发送失败");
                }
                logMap.put("失败说明", errorMsg);
                FormDataBaseManager formDataBaseManager = (FormDataBaseManager) AppContext.getBean("kkBaseFormManager");
                formDataBaseManager.saveUnflowData(Constants.qxbLogformCode, Constants.createUser, logMap);
                return result;
            } catch (Exception e1) {
                logMap.put("调用状态", "失败");
                logMap.put("失败说明", "验证失败，您的系统邮箱设置有误或者邮箱不提供SMTP服务。");
                log.error("验证失败，您的系统邮箱设置有误或者邮箱不提供SMTP服务。", e1);
                try {
                    FormDataBaseManager formDataBaseManager = (FormDataBaseManager) AppContext.getBean("kkBaseFormManager");
                    formDataBaseManager.saveUnflowData(Constants.qxbLogformCode, Constants.createUser, logMap);
                } catch (Exception e) {
                    log.error("kk-邮件发送日志记录异常：", e);
                }
                return false;
            }
        } else {
            return false;
        }
    }

    public boolean sendMessageByMail(List<String> toMailList, String subject, String content, Date sendDate) {
        //kk  记录邮件发送日志  wtt 20200426
        Map<String, Object> logMap = new HashMap<String, Object>();
        logMap.put("接口名称", "系统邮件发送日志");
        logMap.put("调用模块", "邮件发送");//致远插件、启信宝接口
        logMap.put("调用人", "");
        logMap.put("收件人", toMailList);
        logMap.put("抄送人", "");
        logMap.put("经销商名称", subject);
        logMap.put("调用时间", sendDate);
        String errMsg = "";
        if (hasSystemMailbox()) {
            int toMailErrorCount = 0; // 获取收件人邮箱地址不合法出现次数
            boolean toMailFlag = false;
            InternetAddress[] toMailArray = new InternetAddress[toMailList.size()];
            for (int i = 0; i < toMailList.size(); i++) {
                String kkemail = toMailList.get(i);
                // 防止经销商 出现 多个邮箱
                if (-1 != kkemail.indexOf(";")) {
                    String[] tempMail = kkemail.split(";");
                    toMailArray = Arrays.copyOf(toMailArray, toMailArray.length + (tempMail.length - 1));
                    for (int m = 0; m < tempMail.length; m++) {
                        try {
                            toMailArray[i + m] = new InternetAddress(tempMail[m]);
                        } catch (AddressException e) {
                            log.error("#强生客开,邮件地址不合法:" + tempMail[m], e);
                            continue;
                        }
                    }
                    continue;
                }

                try {
                    toMailArray[i] = new InternetAddress(toMailList.get(i));
                } catch (AddressException e) {
                    toMailErrorCount++;
                    logMap.put("调用状态", "失败");
                    errMsg += "邮件地址不合法:" + kkemail + ";";
                    log.error("邮件地址不合法:" + toMailList.get(i), e);
                    continue;
                }
            }

            // kk:处理产品收件人bug，有一个邮箱地址不合法，其他人员也收不到邮件  start
            int tSize = 0;
            if (toMailFlag) {
                tSize = toMailArray.length;
            } else {
                tSize = toMailList.size() - toMailErrorCount;
            }

            InternetAddress[] tMailArray = new InternetAddress[tSize];
            for (int i = 0; i < tMailArray.length; i++) {
                try {
                    tMailArray[i] = new InternetAddress(toMailArray[i].toString());
                } catch (AddressException e) {
                    log.error("#强生客开，邮件地址不合法:" + toMailArray[i], e);
                    continue;
                }
            }

            log.info("toMailArray:" + JSONArray.toJSONString(toMailArray));
            log.info("tMailArray:" + JSONArray.toJSONString(tMailArray));
            // kk: 处理产品收件人bug，有一个邮箱地址不合法，其他人员也收不到邮件 end

            if (toMailArray.length == 0) {
                return false;
            }

            if (session == null) {
                resetSysMailSession();
            }
            Message msg = null;
            try {
                Boolean result = execMailTask(exec, timeOut, subject, content, tMailArray);
                if (result) {
                    logMap.put("调用状态", "发送成功");
                } else {
                    logMap.put("调用状态", "邮件服务发送失败");
                }
                logMap.put("失败说明", errMsg);
                //kk 记录邮件发送日志
                FormDataBaseManager formDataBaseManager = (FormDataBaseManager) AppContext.getBean("kkBaseFormManager");
                formDataBaseManager.saveUnflowData(Constants.qxbLogformCode, Constants.createUser, logMap);
                return result;

            } catch (Exception e1) {
                logMap.put("调用状态", "失败");
                logMap.put("失败说明", "验证失败，您的系统邮箱设置有误或者邮箱不提供SMTP服务。");
                log.error("验证失败，您的系统邮箱设置有误或者邮箱不提供SMTP服务。", e1);
                try {
                    FormDataBaseManager formDataBaseManager = (FormDataBaseManager) AppContext.getBean("kkBaseFormManager");
                    formDataBaseManager.saveUnflowData(Constants.qxbLogformCode, Constants.createUser, logMap);
                } catch (Exception e) {
                    log.error("kk-邮件发送日志记录异常：", e);
                }
                return false;
            }
        } else {
            return false;
        }
    }

    public boolean execMailTask(ExecutorService exec, int timeout, String subject, String content, InternetAddress[] toMailArray) {
        MailTask task = new MailTask(subject, content, toMailArray);
        exec.submit(task);
//	        Future<Boolean> future = exec.submit(task);
//	        Boolean taskResult = Boolean.FALSE;
//	        try {
//	            //等待计算结果，最长等待timeout秒，timeout秒后中止任务          
//	            taskResult = future.get(timeout, TimeUnit.SECONDS);
//	        } catch (InterruptedException e) {
//	            log.error("主线程在邮件发送时被中断！", e);
//	        } catch (ExecutionException e) {
//	            log.error("主线程等待邮件发送，但邮件发送抛出异常！", e);
//	        } catch (TimeoutException e) {
//	            timeOutIndex++;
//	            log.error("邮件第“"+timeOutIndex+"”次发送超时,因此中断任务线程！subject=" + subject + "  发送地址:" + Arrays.asList(toMailArray), e);
//	            //重新获取一次session，再次发送
//	            resetSysMailSession();
//	            if (timeOutIndex < timeOutAmount) {
//	                execMailTask(exec, timeout, subject, content, toMailArray);
//	            }else{
//	                timeOutIndex = 0;
//	                taskResult = false;
//	            }
//	        }
        return true;
    }

    /**
     * #强生客开
     * 添加抄送人
     *
     * @param exec
     * @param timeout
     * @param subject
     * @param content
     * @param toMailArray
     * @param ccMailArray
     * @return
     */
    public boolean execMailTask(ExecutorService exec, int timeout, String subject, String content, InternetAddress[] toMailArray, InternetAddress[] ccMailArray, AffixList affixList) {
        MailTask task = new MailTask(subject, content, toMailArray, ccMailArray, affixList);
        exec.submit(task);
        return true;
    }

    class MailTask implements Callable<Boolean> {
        private String subject;
        private String content;
        private InternetAddress[] toMailArray;
        private InternetAddress[] ccMailArray = null;
        private AffixList affixList = null;

        public MailTask(String subject, String content, InternetAddress[] toMailArray) {
            this.subject = subject;
            this.content = content;
            this.toMailArray = toMailArray;
        }

        /**
         * #强生客开 添加抄送人Mail 构造方法
         *
         * @param subject
         * @param content
         * @param toMailArray
         * @param ccMailArray
         */
        public MailTask(String subject, String content, InternetAddress[] toMailArray, InternetAddress[] ccMailArray, AffixList affixList) {
            this.subject = subject;
            this.content = content;
            this.toMailArray = toMailArray;
            this.ccMailArray = ccMailArray;
            this.affixList = affixList;
        }

        @Override
        public Boolean call() throws Exception {
            Message msg = null;
            MailInfo mi = new MailInfo();
            mi.getSendDate();
            mi.setContentText(content);
            if (suffer.get() != null) {
                mi.setSubject(suffer.get() + subject);
            } else {
                mi.setSubject(subject);
            }
            // #强生客开 添加附件 start
            if (null != affixList) {
                mi.setAffixList(affixList);
                log.info("#强生客开,邮件添加附件：" + mi.getAffixList());
            }
            // #强生客开 end
            msg = MailTools.changFormat(session, mi);
            msg.setFrom(systemMailAddress);
            msg.setRecipients(Message.RecipientType.TO, toMailArray);
            // #强生客开 添加抄送人 start
            if (null != ccMailArray) {
                msg.setRecipients(Message.RecipientType.CC, ccMailArray);
                log.info("sendMessage to mail : toMailArray=[" + JSONArray.toJSONString(toMailArray) + "],ccMailArray=[" + JSONArray.toJSONString(ccMailArray) + "]");
            }
            // #强生客开 end
            Transport.send(msg);
            log.info("sendMessage is ok : toMailArray=[" + JSONArray.toJSONString(toMailArray) + "]");
            return Boolean.TRUE;
        }
    }


    public boolean sendMessageByMail(String toEmail, String subject, String content) {
        return this.sendMessageByMail(toEmail, subject, content, new Date());
    }

    class PasswordAuthenticator extends Authenticator {
        private String username;
        private String password;

        public PasswordAuthenticator(String username, String password) {
            this.username = username;
            this.password = password;
        }

        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
    }

    public void saveSystemMailboxSetting(String emailAddress, String smtpHost, String emailPwd, boolean isAppendLink, int availableTime, String suffer, String userName, int pop3Port, int smtpPort, boolean isSendOnline) {
        String encodePwd = TextEncoder.encode(emailPwd);
        SystemEmailConfig emailConfig = new SystemEmailConfig(emailAddress, smtpHost, encodePwd, isAppendLink, availableTime, suffer, userName, pop3Port, smtpPort, isSendOnline);
        String extConfigValue = XMLCoder.encoder(emailConfig);
        ConfigItem systemMailboxConfigItem = configManager.getConfigItem(SystemMailbox_ConfigCatrgory, SystemMailbox_ConfigItem);
        if (systemMailboxConfigItem != null) {
            systemMailboxConfigItem.setExtConfigValue(extConfigValue);
            configManager.updateConfigItem(systemMailboxConfigItem);
        } else {
            systemMailboxConfigItem = new ConfigItem();
            systemMailboxConfigItem.setIdIfNew();
            systemMailboxConfigItem.setConfigCategory(SystemMailbox_ConfigCatrgory);
            systemMailboxConfigItem.setConfigItem(SystemMailbox_ConfigItem);
            systemMailboxConfigItem.setExtConfigValue(extConfigValue);
            configManager.addConfigItem(systemMailboxConfigItem);
        }

        // 更新Session
        this.MailAddress.set(emailAddress);
        this.SMTPHost.set(smtpHost);
        this.password.set(encodePwd);
        this.contentWithLink.set(isAppendLink);
        this.contentLinkValidity.set(availableTime);
        this.suffer.set(suffer);
        this.userName.set(userName);
        this.pop3Port.set(pop3Port);
        this.smtpPort.set(smtpPort);
        this.isSendOnline.set(isSendOnline);
        try {
            systemMailAddress = new InternetAddress(MailAddress.get());
            hasSystemMailbox.set(true);
        } catch (Exception e) {
            log.error(e.getMessage() + " 系统邮箱Email地址不合法，不能使用邮件发送系统消息!", e);
            hasSystemMailbox.set(false);
        }
//		session = Session.getInstance(this.getProps(SMTPHost,smtpPort+""), new PasswordAuthenticator(userName, emailPwd));
        resetSysMailSession();
    }

    /**
     * 系统管理员测试邮件消息发送
     */
    public boolean testEmailSend(String smtpHostName, String sysEmailAddress, String emailPassword, String recEmailAddress, String userName, String smtpPort) {
        Session testSession = null;
        //testSession = Session.getInstance(this.getProps(smtpHostName,smtpPort), new PasswordAuthenticator(userName, emailPassword));

        int smtpPortNum = Integer.valueOf(smtpPort);
        String decodePwd = TextEncoder.decode(emailPassword);
        try {
            switch (smtpPortNum) {
                case 25:
                    testSession = ConnMailhost.getSmtpSession(smtpHostName, userName, decodePwd);
                    break;
                case 587:
                    testSession = ConnMailhost.getSmtpSessionTLS(smtpHostName, userName, smtpPort, decodePwd);
                    break;
                default:
                    testSession = ConnMailhost.getSmtpSession(smtpHostName, userName, decodePwd, smtpPortNum, false);
                    break;
            }
            Message testMsg = new MimeMessage(testSession);
            String testSubject = "系统管理员测试邮件消息发送";
            testMsg.setHeader("Content-Type", "text/html; charset=UTF-8");
            testMsg.setFrom(new InternetAddress(sysEmailAddress));
            testMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recEmailAddress, false));
            if (suffer.get() != null) {
                testMsg.setSubject(this.suffer.get() + testSubject);
            } else {
                testMsg.setSubject(testSubject);
            }
            testMsg.setContent(testSubject, "text/html; charset=UTF-8");
            testMsg.setSentDate(new Date());
            Transport.send(testMsg);
            return true;
        } catch (Exception e) {
            log.error("系统管理员测试邮件失败：", e);
            return false;
        }
    }

    private Properties getProps(String smtpHostName) {
        Properties props = System.getProperties();
        props.put("mail.smtp.host", smtpHostName);
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.connectiontimeout", "30000");
        props.put("mail.smtp.timeout", "30000");
        return props;
    }

    private Properties getProps(String smtpHostName, String smtpPort) {
        Properties props = System.getProperties();
        props.put("mail.smtp.host", smtpHostName);
        props.put("mail.smtp.port", smtpPort);
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.connectiontimeout", "30000");
        props.put("mail.smtp.timeout", "30000");
        return props;
    }

    public String getMailAddress() {
        return this.MailAddress.get();
    }

    public String getPassword() {
        return this.password.get();
    }

    public String getSMTP() {
        return this.SMTPHost.get();
    }

    public int getContentLinkValidity() {
        return contentLinkValidity.get();
    }

    public boolean isContentWithLink() {
        return contentWithLink.get();
    }

    public SystemEmailConfig getSysEMailConfig() {
        return new SystemEmailConfig(MailAddress.get(), SMTPHost.get(), password.get(), contentWithLink.get(), contentLinkValidity.get(), suffer.get(), userName.get(), pop3Port.get(), smtpPort.get(), isSendOnline.get());
    }

    public void cancelSystemMailboxSetting() {
        ConfigItem systemMailboxConfigItem = configManager.getConfigItem(SystemMailbox_ConfigCatrgory, SystemMailbox_ConfigItem);
        if (systemMailboxConfigItem != null) {
            configManager.deleteConfigItem(SystemMailbox_ConfigCatrgory, SystemMailbox_ConfigItem);
        }

        hasSystemMailbox.set(false);
        systemMailAddress = null;
        MailAddress.set(null);
        SMTPHost.set(null);
        password.set(null);
        session = null;
        contentWithLink.set(false);//取消后不带链接
        suffer.set(null);
        userName.set(null);
    }

    public void resetSysMailSession() {
        int toIntSmtp = smtpPort.get();
        toIntSmtp = toIntSmtp == 0 ? 25 : toIntSmtp;

        smtpPort.set(toIntSmtp);
        ;
        switch (toIntSmtp) {
            case 25:
                session = ConnMailhost.getSmtpSession(SMTPHost.get(), userName.get(), TextEncoder.decode(password.get()));
                break;
            case 587:
                session = ConnMailhost.getSmtpSessionTLS(SMTPHost.get(), userName.get(), smtpPort.get() + "", TextEncoder.decode(password.get()));
                break;
            default:
                session = ConnMailhost.getSmtpSession(SMTPHost.get(), userName.get(), TextEncoder.decode(password.get()), smtpPort.get(), false);
                break;
        }
    }

    public boolean testSendEMail(String smtpHostName, String sysEmailAddress, String emailPassword, String recEmailAddress, String userName, String smtpPort) {
        if (Strings.isBlank(userName) || Strings.isBlank(smtpHostName) || Strings.isBlank(sysEmailAddress) || Strings.isBlank(emailPassword) || Strings.isBlank(recEmailAddress) || Strings.isBlank(smtpPort)) {
            return false;
        }
        return testEmailSend(smtpHostName, sysEmailAddress, emailPassword, recEmailAddress, userName, smtpPort);
    }

}